import { Circle, Point, Rect, Vector } from "../../../core/Layout.js";

abstract class Constraint {
    abstract isInArea(point: Point): boolean
    abstract constraint(point: Point) : Point
}

export class RectConstraint extends Constraint {
    rect: Rect
    constructor(rect: Rect) {
        super()
        this.rect = rect
    }
    isInArea(point: Point): boolean {
        var rect = this.rect
        var a = point.x >= rect.left && point.y >= rect.top
        var b = point.x <= (rect.left + rect.width) && point.y <= (rect.top + rect.height)
        return a && b
    }
    constraint(point: Point): Point {
        if(this.isInArea(point)) return point
        var rect = this.rect
        var x = Math.min(Math.max(point.x, rect.left), rect.left + rect.width)
        var y = Math.min(Math.max(point.y, rect.top), rect.top + rect.height)
        return new Point(x, y)
    }
}

export class CircleConstraint extends Constraint {
    circle: Circle
    constructor(circle: Circle) {
        super()
        this.circle = circle
    }

    distance(point: Point) {
        return Math.sqrt(Math.pow(point.x - this.circle.x, 2) + Math.pow(point.y - this.circle.y, 2))
    }

    isInArea(point: Point): boolean {
        var distance = this.distance(point)
        return distance <= this.circle.r
    }

    constraint(point: Point): Point {
        if(this.isInArea(point)) return point
        var times = this.distance(point) / this.circle.r // 计算距离和半径的倍数
        var vector = new Vector(point.x - this.circle.x, point.y - this.circle.y) // 计算点到圆心的向量
        var intersection = new Point(this.circle.x + vector.dx / times, this.circle.y + vector.dy / times) // 圆心加上变换后的倍数
        return intersection
    }

    getUv(point: Point): Vector {
        return new Vector((point.x - this.circle.x) / this.circle.r, (point.y - this.circle.y) / this.circle.r)
    }
}